package IntelSpam::Filters::BWListFilter;

use 1.0;

use strict;
use warnings;

use IntelSpam::Config;
use Data::Dumper;
use Socket;
use Sys::Hostname;
use Log::Log4perl qw(get_logger);
    

our $VERSION = '1.0';
our $DEBUG = 1;

our $REGISTER = ['connect', 'envfrom', 'envrcpt'];
our $META = {
	'id' => 'bw_filter',
	'name' => 'Black/White List Filter',
	'description' => 'black list or white list filter',
	'version' => '1.0',
	'weight' => 30
	
};

our $logger = get_logger("Intelspam::BWListFilter");

our $CFG = {};

our $has_conf = 0;
our $has_bl = 0;
our $has_wl = 0;

sub new($){
	bless {}, shift;
}

sub filter_connect($$$)
{
	my ($this, $ctx, $hostname) = @_;

	$logger->info("Hostname $hostname");
	if(!$has_conf){
		0;
	}
	my $conf = $CFG->getcfg($META->{'id'});

	my $score = $ctx->getpriv()->{'score'};

	my $ip = gethostbyname($hostname) || 0;
	my $addr = 0;
	if(length $ip == 4){
		$addr = inet_ntoa(scalar($ip));
	}
	
	if($has_bl){
		my $bl = $conf->{'black_list'}->{'item'};

		if(ref($bl) ne 'ARRAY'){
			
			if($bl->{'type'} eq '2'){ #hostname
				
				if($bl->{'content'} eq $hostname){
					$logger->debug("$hostname found in blacklist");
					$score->insert($META->{'id'}, $META->{'weight'}, 20);
				}
			}elsif($bl->{'type'} eq '3'){ #ip
				if($bl->{'content'} eq $ip){
					$logger->debug("$ip found in blacklist");
					$score->insert($META->{'id'}, $META->{'weight'}, 20);
				}
			}
		}else{
			for(my $i = 0; $i < scalar @$bl; $i++){
				my $item = $bl->[$i];
				if($item->{'type'} eq '2'){ #hostname
					if($item->{'content'} eq $hostname){
						$logger->debug("$hostname found in blacklist");
						$score->insert($META->{'id'}, $META->{'weight'}, 20);
					}
				}elsif($item->{'type'} eq '3'){ #ip
					if($item->{'content'} eq $ip){
						$logger->debug("$ip found in blacklist");
						$score->insert($META->{'id'}, $META->{'weight'}, 20);
					}
				}
			}
		}
	}

	if($has_wl){
		my $wl = $conf->{'white_list'}->{'item'};
		if(ref($wl) ne 'ARRAY'){
			if($wl->{'type'} eq '2'){ #hostname
				if($wl->{'content'} eq $hostname){
					$logger->debug("$hostname found in whitelist :)");
					$score->insert($META->{'id'}, $META->{'weight'}, -20);
				}
			}elsif($wl->{'type'} eq '3'){ #ip
				if($wl->{'content'} eq $ip){
					$logger->debug("$ip found in whitelist :)");
					$score->insert($META->{'id'}, $META->{'weight'}, -20);
				}
			}
		}else{
			for(my $i = 0; $i < scalar @$wl; $i++){
				my $item = $wl->[$i];
				if($item->{'type'} eq '2'){ #hostname
					if($item->{'content'} eq $hostname){
						$logger->debug("$hostname found in whitelist :)");
						$score->insert($META->{'id'}, $META->{'weight'}, -20);
					}
				}elsif($item->{'type'} eq '3'){ #ip
					if($item->{'content'} eq $ip){
						$logger->debug("$ip found in whitelist :)");
						$score->insert($META->{'id'}, $META->{'weight'}, -20);
					}
				}
			}
		}
	}
}

sub filter_envfrom($$$)
{
	my ($this, $ctx, $froms) = @_;
	$logger->info("envfrom ". Dumper($froms));
	if(!$has_conf){
		0;
	}
	my $conf = $CFG->getcfg($META->{'id'});
	my $score = $ctx->getpriv()->{'score'};


	if($has_bl){
		my $bl = $conf->{'black_list'}->{'item'};
		if(ref($bl) ne 'ARRAY'){
			if($bl->{'type'} eq '0'){ #from
				foreach my $from (@$froms) {
					if($bl->{'content'} eq $from){
						$logger->debug("$from found in blacklist");
						$score->insert($META->{'id'}, $META->{'weight'}, 20);
					}
				}
			}
		}else{
			for(my $i = 0; $i < scalar @$bl; $i++){
				my $item = $bl->[$i];
			
				if($item->{'type'} eq '0'){ #from
					foreach my $from (@$froms) {
						if($item->{'content'} eq $from){
							$logger->debug("$from found in blacklist");
							$score->insert($META->{'id'}, $META->{'weight'}, 20);
						}
					}
				}
			}
		}
	}

	if($has_wl){
		my $wl = $conf->{'white_list'}->{'item'};
		if(ref($wl) ne 'ARRAY'){
			if($wl->{'type'} eq '0'){ #from
				foreach my $from (@$froms) {
					if($wl->{'content'} eq $from){
						$logger->debug("$from found in whitelist ;)");
						$score->insert($META->{'id'}, $META->{'weight'}, -20);
					}
				}
			}
		}else{
			for(my $i = 0; $i < scalar @$wl; $i++){
				my $item = $wl->[$i];
				if($item->{'type'} eq '0'){ #from
					foreach my $from (@$froms) {
						if($item->{'content'} eq $from){
							$logger->debug("$from found in whitelist ;)");
							$score->insert($META->{'id'}, $META->{'weight'}, -20);
						}
					}
				}
			}
		}
	}
}

sub filter_envrcpt($$$)
{
	my ($this, $ctx, $rcpts) = @_;

	$logger->info("envfrom " . Dumper($rcpts));
	if(!$has_conf){
		0;
	}

	my $conf = $CFG->getcfg($META->{'id'});
	my $score = $ctx->getpriv()->{'score'};

	if($has_bl){
		my $bl = $conf->{'black_list'}->{'item'};
		if(ref($bl) ne 'ARRAY'){
			if($bl->{'type'} eq '1'){ #to
				foreach my $rcpt (@$rcpts) {
					if($bl->{'content'} eq $rcpt){
						$logger->debug("$rcpt found in blacklist");
						$score->insert($META->{'id'}, $META->{'weight'}, 20);
					}
				}
			}
		}else{
			for(my $i = 0; $i < scalar @$bl; $i++){
				my $item = $bl->[$i];
				if($item->{'type'} eq '1'){ #to
					foreach my $rcpt (@$rcpts) {
						if($item->{'content'} eq $rcpt){
							$logger->debug("$rcpt found in blacklist");
							$score->insert($META->{'id'}, $META->{'weight'}, 20);
						}
					}
				}
			}
		}
	}

	if($has_wl){
		my $wl = $conf->{'white_list'}->{'item'};

		if(ref($wl) ne 'ARRAY'){
			if($wl->{'type'} eq '1'){ #from
				foreach my $rcpt (@$rcpts) {
					if($wl->{'content'} eq $rcpt){
						$logger->debug("$rcpt found in whitelist :)");
						$score->insert($META->{'id'}, $META->{'weight'}, -20);
					}
				}
			}
		}else{
			for(my $i = 0; $i < scalar @$wl; $i++){
				my $item = $wl->[$i];
				if($item->{'type'} eq '1'){ #from
					foreach my $rcpt (@$rcpts) {
						if($item->{'content'} eq $rcpt){
							$logger->debug("$rcpt found in whitelist :)");
							$score->insert($META->{'id'}, $META->{'weight'}, -20);
						}
					}
				}
			}
		}
	}
}

sub get_registers($){
	$REGISTER;
}

sub get_meta($){
	$META;
}

sub set_cfg($$){
	my $this = shift;
	$CFG = shift;

	my $conf = $CFG->getcfg($META->{'id'});
	$has_conf = defined $conf;

	if($has_conf){
		
		$has_bl = defined $conf->{'black_list'} && defined $conf->{'black_list'}->{'item'};
		$has_wl = defined $conf->{'white_list'} && defined $conf->{'white_list'}->{'item'};
	}
	
}

1;
